This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

library(dplyr)
library(ggplot2)
library(tidyr)
library(car)
library(MASS)
library(repr)
library(pals)
getwd()
[1] "C:/Users/Natalie/git_proj/Is-your-electric-car-overpriced-"
ecars_raw = ecars_raw %>% rename(Price = Price.DE., Acceleration = acceleration..0.100.)
Error in `rename()`:
! Can't rename columns that don't exist.
✖ Column `Price.DE.` doesn't exist.
Backtrace:
 1. ecars_raw %>% rename(Price = Price.DE., Acceleration = acceleration..0.100.)
 3. dplyr:::rename.data.frame(., Price = Price.DE., Acceleration = acceleration..0.100.)
make = strsplit(ecars_raw$Car_name, split = ' ')

make_ = c()
n = length(make)

for (i in 1:n) {
  make_[i] = make[[i]][1]
}

ecars_raw$Make = make_
ecars_raw = ecars_raw %>% relocate(Make, .before = Car_name_link)
ecars_raw = ecars_raw %>% relocate(Battery, .after = Car_name_link)
ecars_raw
make_colors = c('#e6194b', '#f58231',  '#ffe119', 
                '#bcf60c','#3cb44b', '#008080',
                '#aaffc3', '#4363d8', '#000075',
                '#46f0f0', '#911eb4', '#e6beff',
                '#f032e6', '#fabebe')
summary(price_model_full)

Call:
lm(formula = Price ~ Battery + Efficiency + Fast_charge + Range + 
    Top_speed + Acceleration, data = ecars)

Residuals:
   Min     1Q Median     3Q    Max 
-53557 -11739   -178   8223  84430 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)  -1.613e+05  2.398e+04  -6.724 8.91e-11 ***
Battery       2.215e+02  3.506e+02   0.632  0.52798    
Efficiency    3.052e+02  1.140e+02   2.678  0.00781 ** 
Fast_charge   1.785e+01  7.819e+00   2.283  0.02315 *  
Range         9.066e+00  6.679e+01   0.136  0.89211    
Top_speed     7.013e+02  7.086e+01   9.897  < 2e-16 ***
Acceleration  1.762e+03  7.746e+02   2.274  0.02366 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 18530 on 300 degrees of freedom
Multiple R-squared:  0.7167,    Adjusted R-squared:  0.711 
F-statistic: 126.5 on 6 and 300 DF,  p-value: < 2.2e-16
forwardAIC = step(price_model_empty, scope, direction = 'forward', k = 2)
Start:  AIC=6415.84
Price ~ 1

               Df  Sum of Sq        RSS    AIC
+ Top_speed     1 2.1023e+11 1.5319e+11 6152.6
+ Battery       1 1.7911e+11 1.8431e+11 6209.4
+ Fast_charge   1 1.3923e+11 2.2419e+11 6269.5
+ Range         1 1.2615e+11 2.3728e+11 6287.0
+ Acceleration  1 1.0296e+11 2.6046e+11 6315.6
+ Efficiency    1 1.1067e+10 3.5235e+11 6408.3
<none>                       3.6342e+11 6415.8

Step:  AIC=6152.62
Price ~ Top_speed

               Df  Sum of Sq        RSS    AIC
+ Efficiency    1 4.2802e+10 1.1039e+11 6054.0
+ Battery       1 1.9965e+10 1.3322e+11 6111.8
+ Acceleration  1 1.5065e+10 1.3812e+11 6122.8
<none>                       1.5319e+11 6152.6
+ Fast_charge   1 2.2387e+08 1.5297e+11 6154.2
+ Range         1 7.0491e+07 1.5312e+11 6154.5

Step:  AIC=6054.03
Price ~ Top_speed + Efficiency

               Df  Sum of Sq        RSS    AIC
+ Fast_charge   1 3519695484 1.0687e+11 6046.1
+ Range         1 3506122724 1.0688e+11 6046.1
+ Battery       1 3063673448 1.0732e+11 6047.4
+ Acceleration  1  915987463 1.0947e+11 6053.5
<none>                       1.1039e+11 6054.0

Step:  AIC=6046.08
Price ~ Top_speed + Efficiency + Fast_charge

               Df  Sum of Sq        RSS    AIC
+ Range         1 2137906570 1.0473e+11 6041.9
+ Battery       1 2032210165 1.0484e+11 6042.2
+ Acceleration  1  713779942 1.0615e+11 6046.0
<none>                       1.0687e+11 6046.1

Step:  AIC=6041.87
Price ~ Top_speed + Efficiency + Fast_charge + Range

               Df  Sum of Sq        RSS    AIC
+ Acceleration  1 1639080066 1.0309e+11 6039.0
<none>                       1.0473e+11 6041.9
+ Battery       1    1076868 1.0473e+11 6043.9

Step:  AIC=6039.03
Price ~ Top_speed + Efficiency + Fast_charge + Range + Acceleration

          Df Sum of Sq        RSS    AIC
<none>                 1.0309e+11 6039.0
+ Battery  1  1.37e+08 1.0295e+11 6040.6
summary(price_model)

Call:
lm(formula = Price_lambda ~ Efficiency + Fast_charge + Range + 
    Top_speed + Acceleration, data = ecars)

Residuals:
       Min         1Q     Median         3Q        Max 
-2.951e-04 -4.127e-05  8.710e-06  4.794e-05  1.467e-04 

Coefficients:
               Estimate Std. Error   t value Pr(>|t|)    
(Intercept)   1.413e+00  5.206e-05 27130.409  < 2e-16 ***
Efficiency    3.059e-06  1.332e-07    22.957  < 2e-16 ***
Fast_charge   1.407e-07  2.675e-08     5.259 2.75e-07 ***
Range         5.510e-07  5.805e-08     9.491  < 2e-16 ***
Top_speed     1.601e-06  2.455e-07     6.524 2.89e-10 ***
Acceleration -4.715e-06  2.603e-06    -1.812    0.071 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 6.436e-05 on 301 degrees of freedom
Multiple R-squared:  0.853, Adjusted R-squared:  0.8505 
F-statistic: 349.3 on 5 and 301 DF,  p-value: < 2.2e-16
prediction = predict(price_model, ecars, interval = 'prediction')
confidence = predict(price_model, ecars, interval = 'confidence')
prediction_dollars = ((prediction * lambda) + 1)^(1/lambda)
confidence_dollars = ((confidence * lambda) + 1)^(1/lambda)
predicted_price = data.frame(Name = ecars$Car_name,
                             Make = ecars$Make,
                             Price = ecars$Price/1000,
                             Predicted = (prediction_dollars[,1]/1000),
                             Predict_lwr = (prediction_dollars[,2]/1000),
                             Predict_upr = (prediction_dollars[,3]/1000),
                             Confidence_lwr = (confidence_dollars[,2]/1000),
                             Confidence_upr = (confidence_dollars[,3]/1000))
predicted_price
ggplot(NULL, aes(Predicted_price, Price)) +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Predicted), col = 'black', linetype = 'dashed') +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_lwr), col = 'red', linetype = 'dashed') +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_upr), col = 'red') +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_lwr), col = 'blue') +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_upr), col = 'blue') +
      geom_ribbon(aes(ymin = predicted_price$Confidence_lwr, ymax = predicted_price$Confidence_upr), fill = "grey70")+
      ylim(25,150) + xlim(25, 140) +
      geom_point(data = predicted_price, aes(x = Predicted, y = Price), alpha = .5) + 
      geom_point(data = most_makes, aes(x = mean_predicted, y = mean_price, col = Make), size = 3) +
      scale_color_manual(values = make_colors) +
      xlab("Predicted Price in 1000s of Euros") + ylab("Price in 1000s of Euros") +
      ggtitle('Price of Electric Vehicles with mean cost per Make')
Error in `geom_ribbon()`:
! Problem while computing aesthetics.
ℹ Error occurred in the 6th layer.
Caused by error:
! object 'Predicted_price' not found
Backtrace:
  1. base (local) `<fn>`(x)
  2. ggplot2:::print.ggplot(x)
  4. ggplot2:::ggplot_build.ggplot(x)
  5. ggplot2:::by_layer(...)
 12. ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 13. l$compute_aesthetics(d, plot)
 14. ggplot2 (local) compute_aesthetics(..., self = self)
 15. base::lapply(aesthetics, eval_tidy, data = data, env = env)
 16. rlang (local) FUN(X[[i]], ...)



testa = ggplot(NULL, aes(Predicted_price, Price)) +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Predicted), 
                  col = 'blue', size = .8, alpha = .5) +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_lwr), 
                  col = 'red', linetype = 'dashed', size = .8, alpha = .8) +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Predict_upr), 
                  col = 'red', linetype = 'dashed',size = .8, alpha = .8) +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_lwr), 
                  col = 'black', linetype = 'dashed', size = .8, alpha = .8) +
      geom_smooth(data = predicted_price, aes(x = Predicted, y = Confidence_upr), 
                  col = 'black', linetype = 'dashed', size = .8, alpha = .8) +
      geom_point(data = predicted_price, aes(x = Predicted, y = Price, text = Name), alpha = .5) +
      theme(legend.position = "right", legend.text = element_text(size = 8))+
      ylim(25, 250) + xlim(25, 250) +
      labs(title = "Predicted Price vs. Price for all EV Models",
           caption = "Data source: ToothGrowth",
           x = "Predicted price (euros in thousands)", y = "German Price (euros in thousands)",
           tag = "A")
Warning: Ignoring unknown aesthetics: text
ggplotly(testa, tooltip = c("x", 'y', "text")) 
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 4 rows containing non-finite values (`stat_smooth()`).`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 8 rows containing non-finite values (`stat_smooth()`).`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 1 rows containing non-finite values (`stat_smooth()`).`geom_smooth()` using method = 'loess' and formula = 'y ~ x'Warning: Removed 1 rows containing non-finite values (`stat_smooth()`).

unique(ecars_missing_price$Make)
 [1] "Rolls-Royce" "Hongqi"      "Audi"        "Peugeot"     "Mercedes"    "Opel"        "Polestar"    "Hyundai"    
 [9] "Volkswagen"  "XPENG"       "CUPRA"       "Genesis"     "Maserati"    "Mini"        "Seres"       "Volvo"      
[17] "Ford"        "Lexus"       "Skoda"       "Fiat"        "Kia"         "Toyota"     

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeSh0aWR5cikNCmxpYnJhcnkoY2FyKQ0KbGlicmFyeShNQVNTKQ0KbGlicmFyeShyZXByKQ0KbGlicmFyeShwYWxzKQ0KYGBgDQpgYGB7cn0NCmdldHdkKCkNCmVjYXJzX3JhdyA9IHJlYWQuY3N2KCdFVl9jYXJzLmNzdicpDQoNCmBgYA0KYGBge3J9DQplY2Fyc19yYXcgPSBlY2Fyc19yYXcgJT4lIHJlbmFtZShQcmljZSA9IFByaWNlLkRFLiwgQWNjZWxlcmF0aW9uID0gYWNjZWxlcmF0aW9uLi4wLjEwMC4pDQpgYGANCg0KYGBge3J9DQptYWtlID0gc3Ryc3BsaXQoZWNhcnNfcmF3JENhcl9uYW1lLCBzcGxpdCA9ICcgJykNCg0KbWFrZV8gPSBjKCkNCm4gPSBsZW5ndGgobWFrZSkNCg0KZm9yIChpIGluIDE6bikgew0KICBtYWtlX1tpXSA9IG1ha2VbW2ldXVsxXQ0KfQ0KDQplY2Fyc19yYXckTWFrZSA9IG1ha2VfDQpgYGANCg0KDQpgYGB7cn0NCmVjYXJzX3JhdyA9IGVjYXJzX3JhdyAlPiUgcmVsb2NhdGUoTWFrZSwgLmJlZm9yZSA9IENhcl9uYW1lX2xpbmspDQplY2Fyc19yYXcgPSBlY2Fyc19yYXcgJT4lIHJlbG9jYXRlKEJhdHRlcnksIC5hZnRlciA9IENhcl9uYW1lX2xpbmspDQplY2Fyc19yYXcNCmBgYA0KDQpgYGB7cn0NCmVjYXJzX3JhdyA9IGVjYXJzX3JhdyAlPiUgZmlsdGVyKCFpcy5uYShGYXN0X2NoYXJnZSkpDQplY2FycyA9IGVjYXJzX3JhdyAlPiUgZmlsdGVyKCFpcy5uYShQcmljZSkpDQplY2Fyc19taXNzaW5nX3ByaWNlID0gZWNhcnNfcmF3ICU+JSBmaWx0ZXIoaXMubmEoUHJpY2UpKQ0Kd3JpdGUuY3N2KGVjYXJzLGZpbGU9Jy9Vc2Vycy9OYXRhbGllL2dpdF9wcm9qL0lzLXlvdXItZWxlY3RyaWMtY2FyLW92ZXJwcmljZWQtL2VjYXJzLmNzdicsIHJvdy5uYW1lcz1GQUxTRSkNCndyaXRlLmNzdihtb3N0X21ha2VzLGZpbGU9Jy9Vc2Vycy9OYXRhbGllL2dpdF9wcm9qL0lzLXlvdXItZWxlY3RyaWMtY2FyLW92ZXJwcmljZWQtL21vc3RfbWFrZXMuY3N2Jywgcm93Lm5hbWVzPUZBTFNFKQ0KDQpgYGANCmBgYHtyfQ0KbWFrZV9jb2xvcnMgPSBjKCcjZTYxOTRiJywgJyNmNTgyMzEnLCAgJyNmZmUxMTknLCANCiAgICAgICAgICAgICAgICAnI2JjZjYwYycsJyMzY2I0NGInLCAnIzAwODA4MCcsDQogICAgICAgICAgICAgICAgJyNhYWZmYzMnLCAnIzQzNjNkOCcsICcjMDAwMDc1JywNCiAgICAgICAgICAgICAgICAnIzQ2ZjBmMCcsICcjOTExZWI0JywgJyNlNmJlZmYnLA0KICAgICAgICAgICAgICAgICcjZjAzMmU2JywgJyNmYWJlYmUnKQ0KYGBgDQoNCmBgYHtyfQ0KcHJpY2VfbW9kZWxfZW1wdHkgPSBsbShQcmljZSB+IDEsIGRhdGEgPSBlY2FycykNCnByaWNlX21vZGVsX2Z1bGw9IGxtKFByaWNlIH4gQmF0dGVyeSArIEVmZmljaWVuY3kgKyBGYXN0X2NoYXJnZSArIFJhbmdlICsgVG9wX3NwZWVkICsgQWNjZWxlcmF0aW9uLCBkYXRhID0gZWNhcnMpDQpzdW1tYXJ5KHByaWNlX21vZGVsX2Z1bGwpDQpgYGANCmBgYHtyfQ0KZWNhcnNfbWlzc2luZ19wcmljZQ0KYGBgDQoNCmBgYHtyfQ0Kc2NvcGUgPSBsaXN0KGxvd2VyID0gZm9ybXVsYShwcmljZV9tb2RlbF9lbXB0eSksIHVwcGVyID0gZm9ybXVsYShwcmljZV9tb2RlbF9mdWxsKSkNCmZvcndhcmRBSUMgPSBzdGVwKHByaWNlX21vZGVsX2VtcHR5LCBzY29wZSwgZGlyZWN0aW9uID0gJ2ZvcndhcmQnLCBrID0gMikNCmBgYA0KDQpgYGB7cn0NCnByaWNlX21vZGVsX2luaXRpYWwgPSBsbShQcmljZSB+IEVmZmljaWVuY3kgKyBGYXN0X2NoYXJnZSArIFJhbmdlICsgVG9wX3NwZWVkICsgQWNjZWxlcmF0aW9uLCBkYXRhID0gZWNhcnMpDQpzdW1tYXJ5KHByaWNlX21vZGVsX2luaXRpYWwpDQpiYyA9IGJveENveChwcmljZV9tb2RlbF9pbml0aWFsKQ0KbGFtYmRhID0gYmMkeFt3aGljaChiYyR5ID09IG1heChiYyR5KSldDQplY2FycyRQcmljZV9sYW1iZGEgPSAoZWNhcnMkUHJpY2VebGFtYmRhIC0gMSkvbGFtYmRhDQpwcmljZV9tb2RlbCA9IGxtKFByaWNlX2xhbWJkYSB+IEVmZmljaWVuY3kgKyBGYXN0X2NoYXJnZSArIFJhbmdlICsgVG9wX3NwZWVkICsgQWNjZWxlcmF0aW9uLCBkYXRhID0gZWNhcnMpDQpzdW1tYXJ5KHByaWNlX21vZGVsKQ0KcGxvdChwcmljZV9tb2RlbCkNCmJyb29tOjpnbGFuY2UocHJpY2VfbW9kZWwpDQpgYGANCg0KYGBge3J9DQpwcmVkaWN0aW9uID0gcHJlZGljdChwcmljZV9tb2RlbCwgZWNhcnMsIGludGVydmFsID0gJ3ByZWRpY3Rpb24nKQ0KY29uZmlkZW5jZSA9IHByZWRpY3QocHJpY2VfbW9kZWwsIGVjYXJzLCBpbnRlcnZhbCA9ICdjb25maWRlbmNlJykNCnByZWRpY3Rpb25fZG9sbGFycyA9ICgocHJlZGljdGlvbiAqIGxhbWJkYSkgKyAxKV4oMS9sYW1iZGEpDQpjb25maWRlbmNlX2RvbGxhcnMgPSAoKGNvbmZpZGVuY2UgKiBsYW1iZGEpICsgMSleKDEvbGFtYmRhKQ0KcHJlZGljdGVkX3ByaWNlID0gZGF0YS5mcmFtZShOYW1lID0gZWNhcnMkQ2FyX25hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ha2UgPSBlY2FycyRNYWtlLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmljZSA9IGVjYXJzJFByaWNlLzEwMDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY3RlZCA9IChwcmVkaWN0aW9uX2RvbGxhcnNbLDFdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVkaWN0X2x3ciA9IChwcmVkaWN0aW9uX2RvbGxhcnNbLDJdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcmVkaWN0X3VwciA9IChwcmVkaWN0aW9uX2RvbGxhcnNbLDNdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25maWRlbmNlX2x3ciA9IChjb25maWRlbmNlX2RvbGxhcnNbLDJdLzEwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25maWRlbmNlX3VwciA9IChjb25maWRlbmNlX2RvbGxhcnNbLDNdLzEwMDApKQ0KcHJlZGljdGVkX3ByaWNlDQp3cml0ZS5jc3YocHJlZGljdGVkX3ByaWNlLGZpbGU9Jy9Vc2Vycy9OYXRhbGllL2dpdF9wcm9qL0lzLXlvdXItZWxlY3RyaWMtY2FyLW92ZXJwcmljZWQtL3ByZWRpY3RlZF9wcmljZS5jc3YnLCByb3cubmFtZXM9RkFMU0UpDQpgYGANCmBgYHtyfQ0KbW9zdF9tYWtlcyA9IHByZWRpY3RlZF9wcmljZSAlPiUNCiAgZ3JvdXBfYnkoTWFrZSklPiUNCiAgZmlsdGVyKG4oKSA+PSAxMCkgJT4lDQogIHN1bW1hcmlzZShtZWFuX3ByaWNlID0gbWVhbihQcmljZSksIG1lYW5fcHJlZGljdGVkID0gbWVhbihQcmVkaWN0ZWQpKQ0KbW9zdF9tYWtlcw0KYGBgDQpgYGB7cn0NCnByZWRpY3RlZF9wcmljZSAlPiUNCiAgZmlsdGVyKE1ha2UgPT0gJ1BvcnNjaGUnKQ0KYGBgDQoNCg0KYGBge3J9DQoNCmdncGxvdChOVUxMLCBhZXMoUHJlZGljdGVkX3ByaWNlLCBQcmljZSkpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdGVkKSwgY29sID0gJ2JsYWNrJykgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X2x3ciksIGNvbCA9ICdyZWQnKSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfdXByKSwgY29sID0gJ3JlZCcpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV9sd3IpLCBjb2wgPSAnYmx1ZScpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV91cHIpLCBjb2wgPSAnYmx1ZScpICsNCiAgICAgIHlsaW0oMCwzMDApICsNCiAgICAgIGdlb21fcG9pbnQoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmljZSksIGFscGhhID0gLjUpICsNCiAgICAgIGdlb21fcG9pbnQoZGF0YSA9IG1vc3RfbWFrZXMsIGFlcyh4ID0gbWVhbl9wcmVkaWN0ZWQsIHkgPSBtZWFuX3ByaWNlLCBjb2wgPSBNYWtlKSwgc2l6ZSA9IDMpICsNCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBtYWtlX2NvbG9ycykNCg0KZ2dwbG90KE5VTEwsIGFlcyhQcmVkaWN0ZWRfcHJpY2UsIFByaWNlKSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0ZWQpLCBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnKSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfbHdyKSwgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdF91cHIpLCBjb2wgPSAncmVkJykgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBDb25maWRlbmNlX2x3ciksIGNvbCA9ICdibHVlJykgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBDb25maWRlbmNlX3VwciksIGNvbCA9ICdibHVlJykgKw0KICAgICAgeWxpbSgyNSwxNTApICsgeGxpbSgyNSwgMTQwKSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJpY2UpLCBhbHBoYSA9IC41KSArIA0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByZWRpY3RlZCwgeSA9IG1lYW5fcHJpY2UsIGNvbCA9IE1ha2UpLCBzaXplID0gMykgKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG1ha2VfY29sb3JzKSArDQogICAgICB4bGFiKCJQcmVkaWN0ZWQgUHJpY2UgaW4gMTAwMHMgb2YgRXVyb3MiKSArIHlsYWIoIlByaWNlIGluIDEwMDBzIG9mIEV1cm9zIikgKw0KICAgICAgZ2d0aXRsZSgnUHJpY2Ugb2YgRWxlY3RyaWMgVmVoaWNsZXMgd2l0aCBtZWFuIGNvc3QgcGVyIE1ha2UnKQ0KDQoNCiMgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByaWNlLCB5ID0gbWVhbl9wcmVkaWN0ZWQpLCBzaXplID0gMywgc2hhcGUgPSAyMywgZmlsbCA9IG1ha2VfY29sb3JzKSArDQoNCg0KYGBgDQpgYGB7cn0NCiAgIA0KICAgIGdncGxvdChOVUxMLCBhZXMoUHJlZGljdGVkX3ByaWNlLCBQcmljZSkpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdGVkKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmx1ZScsIHNpemUgPSAuNSwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X2x3ciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIGFscGhhID0gLjgpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdF91cHIpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdyZWQnLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IENvbmZpZGVuY2VfbHdyKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IENvbmZpZGVuY2VfdXByKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJpY2UpLCBhbHBoYSA9IC41KSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBtb3N0X21ha2VzLCBhZXMoeCA9IG1lYW5fcHJlZGljdGVkLCB5ID0gbWVhbl9wcmljZSksIHNpemUgPSAzKSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBtb3N0X21ha2VzLCBhZXMoeCA9IG1lYW5fcHJlZGljdGVkLCB5ID0gbWVhbl9wcmljZSwgY29sID0gTWFrZSksIHNpemUgPSAyKSArDQogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIiwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSsNCiAgICAgIHlsaW0oMjUsIDI1MCkgKyB4bGltKDI1LCAyNTApICsNCiAgICAgIHhsYWIoIlByZWRpY3RlZCBwcmljZSAoZXVyb3MgaW4gdGhvdXNhbmRzKSIpICsgeWxhYigiUHJpY2UgKGV1cm9zIGluIHRob3VzYW5kcykiKSArDQogICAgICBnZ3RpdGxlKCdQcmVkaWN0ZWQgUHJpY2UgdnMuIFByaWNlIGZvciBhbGwgRVYgTW9kZWxzJykgIA0KYGBgDQoNCmBgYHtyfQ0KIGdncGxvdChOVUxMLCBhZXMoUHJlZGljdGVkX3ByaWNlLCBQcmljZSkpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJlZGljdGVkKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmx1ZScsIHNpemUgPSAuOCwgYWxwaGEgPSAuNSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X2x3ciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIHNpemUgPSAuOCwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0X3VwciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ3JlZCcsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsc2l6ZSA9IC44LCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IENvbmZpZGVuY2VfbHdyKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAnYmxhY2snLCBsaW5ldHlwZSA9ICdkYXNoZWQnLCBzaXplID0gLjgsIGFscGhhID0gLjgpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV91cHIpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdibGFjaycsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIHNpemUgPSAuOCwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByaWNlKSwgYWxwaGEgPSAuNSkgKw0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByZWRpY3RlZCwgeSA9IG1lYW5fcHJpY2UpLCBzaXplID0gMykgKw0KICAgICAgZ2VvbV9wb2ludChkYXRhID0gbW9zdF9tYWtlcywgYWVzKHggPSBtZWFuX3ByZWRpY3RlZCwgeSA9IG1lYW5fcHJpY2UsIGNvbCA9IE1ha2UpLCBzaXplID0gMikgKw0KICAgICAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IG1ha2VfY29sb3JzKSArDQogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCkpKw0KICAgICAgeWxpbSgyNSwgMTQwKSArIHhsaW0oMjUsIDExMCkgKw0KICAgICAgbGFicyh0aXRsZSA9ICJQcmVkaWN0ZWQgUHJpY2UgdnMuIFByaWNlIGZvciBhbGwgRVYgTW9kZWxzIiwNCiAgICAgICAgICAgc3VidGl0bGUgPSAiTWVhbiBtb2RlbCBwcmljZSBmb3IgbWFrZXMgd2l0aCAxMCsgbW9kZWxzIGluY2x1ZGVkIiwNCiAgICAgICAgICAgY2FwdGlvbiA9ICJEYXRhIHNvdXJjZTogVG9vdGhHcm93dGgiLA0KICAgICAgICAgICB4ID0gIlByZWRpY3RlZCBwcmljZSAoZXVyb3MgaW4gdGhvdXNhbmRzKSIsIHkgPSAiR2VybWFuIFByaWNlIChldXJvcyBpbiB0aG91c2FuZHMpIiwNCiAgICAgICAgICAgdGFnID0gIkEiKQ0KYGBgDQoNCmBgYHtyfQ0KDQoNCnRlc3RhID0gZ2dwbG90KE5VTEwsIGFlcyhQcmVkaWN0ZWRfcHJpY2UsIFByaWNlKSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBQcmVkaWN0ZWQpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdibHVlJywgc2l6ZSA9IC44LCBhbHBoYSA9IC41KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfbHdyKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAncmVkJywgbGluZXR5cGUgPSAnZGFzaGVkJywgc2l6ZSA9IC44LCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3Ntb290aChkYXRhID0gcHJlZGljdGVkX3ByaWNlLCBhZXMoeCA9IFByZWRpY3RlZCwgeSA9IFByZWRpY3RfdXByKSwgDQogICAgICAgICAgICAgICAgICBjb2wgPSAncmVkJywgbGluZXR5cGUgPSAnZGFzaGVkJyxzaXplID0gLjgsIGFscGhhID0gLjgpICsNCiAgICAgIGdlb21fc21vb3RoKGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gQ29uZmlkZW5jZV9sd3IpLCANCiAgICAgICAgICAgICAgICAgIGNvbCA9ICdibGFjaycsIGxpbmV0eXBlID0gJ2Rhc2hlZCcsIHNpemUgPSAuOCwgYWxwaGEgPSAuOCkgKw0KICAgICAgZ2VvbV9zbW9vdGgoZGF0YSA9IHByZWRpY3RlZF9wcmljZSwgYWVzKHggPSBQcmVkaWN0ZWQsIHkgPSBDb25maWRlbmNlX3VwciksIA0KICAgICAgICAgICAgICAgICAgY29sID0gJ2JsYWNrJywgbGluZXR5cGUgPSAnZGFzaGVkJywgc2l6ZSA9IC44LCBhbHBoYSA9IC44KSArDQogICAgICBnZW9tX3BvaW50KGRhdGEgPSBwcmVkaWN0ZWRfcHJpY2UsIGFlcyh4ID0gUHJlZGljdGVkLCB5ID0gUHJpY2UsIHRleHQgPSBOYW1lKSwgYWxwaGEgPSAuNSkgKw0KICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInJpZ2h0IiwgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgpKSsNCiAgICAgIHlsaW0oMjUsIDI1MCkgKyB4bGltKDI1LCAyNTApICsNCiAgICAgIGxhYnModGl0bGUgPSAiUHJlZGljdGVkIFByaWNlIHZzLiBQcmljZSBmb3IgYWxsIEVWIE1vZGVscyIsDQogICAgICAgICAgIGNhcHRpb24gPSAiRGF0YSBzb3VyY2U6IFRvb3RoR3Jvd3RoIiwNCiAgICAgICAgICAgeCA9ICJQcmVkaWN0ZWQgcHJpY2UgKGV1cm9zIGluIHRob3VzYW5kcykiLCB5ID0gIkdlcm1hbiBQcmljZSAoZXVyb3MgaW4gdGhvdXNhbmRzKSIsDQogICAgICAgICAgIHRhZyA9ICJBIikNCg0KZ2dwbG90bHkodGVzdGEsIHRvb2x0aXAgPSBjKCJ4IiwgJ3knLCAidGV4dCIpKSANCmBgYA0KDQpgYGB7cn0NCmVjYXJzDQpnZ3Bsb3QoZGF0YSA9IGVjYXJzLCBhZXMoeCA9IEJhdHRlcnksIHkgPSBQcmljZSkpICsgDQogIGdlb21fcG9pbnQoKQ0KYGBgDQoNCmBgYHtyfQ0KdW5pcXVlKGVjYXJzX21pc3NpbmdfcHJpY2UkTWFrZSkNCg0KYGBgDQoNCmBgYHtyfQ0KcHJlZGljdGlvbl9taXNzaW5nID0gcHJlZGljdChwcmljZV9tb2RlbCwgZWNhcnNfbWlzc2luZ19wcmljZSwgaW50ZXJ2YWwgPSAncHJlZGljdGlvbicpDQpwcmVkaWN0aW9uX21pc3NpbmcNCnByZWRpY3Rpb25fbWlzc2luZ19kb2xsYXJzID0gKChwcmVkaWN0aW9uX21pc3NpbmcgKiBsYW1iZGEpICsgMSleKDEvbGFtYmRhKQ0KDQpwcmVkaWN0ZWRfbWlzc2luZ19wcmljZSA9IGRhdGEuZnJhbWUoTmFtZSA9IGVjYXJzX21pc3NpbmdfcHJpY2UkQ2FyX25hbWUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1ha2UgPSBlY2Fyc19taXNzaW5nX3ByaWNlJE1ha2UsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFByZWRpY3RlZCA9IChwcmVkaWN0aW9uX21pc3NpbmdfZG9sbGFyc1ssMV0vMTAwMCkpDQogICAgICAgICAgICAgICAgICAgICAgICAgICANCnByZWRpY3RlZF9taXNzaW5nX3ByaWNlDQpgYGANCg0KYGBge3J9DQpwcmVkaWN0ZWRfbWlzc2luZ19wcmljZSAlPiUNCiAgZ3JvdXBfYnkoTWFrZSkgJT4lDQogIGZpbHRlcihuKCk+PTMpDQoNCnByZWRpY3RlZF9taXNzaW5nX3ByaWNlICU+JQ0KICBmaWx0ZXIoTWFrZSA9PSAnUm9sbHMtUm95Y2UnKQ0KYGBgDQoNCmBgYHtyfQ0Kc3VtbWFyeShwcmljZV9tb2RlbCkNCnBsb3QocHJpY2VfbW9kZWwpDQpzYXZlUkRTKHByaWNlX21vZGVsLCAibW9kZWwucmRzIikNCmBgYA0KDQpgYGB7cn0NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7cn0NCg0KYGBgDQoNCmBgYHtyfQ0KDQpgYGANCg0KYGBge3J9DQoNCmBgYA0KDQpBZGQgYSBuZXcgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpJbnNlcnQgQ2h1bmsqIGJ1dHRvbiBvbiB0aGUgdG9vbGJhciBvciBieSBwcmVzc2luZyAqQ3RybCtBbHQrSSouDQoNCldoZW4geW91IHNhdmUgdGhlIG5vdGVib29rLCBhbiBIVE1MIGZpbGUgY29udGFpbmluZyB0aGUgY29kZSBhbmQgb3V0cHV0IHdpbGwgYmUgc2F2ZWQgYWxvbmdzaWRlIGl0IChjbGljayB0aGUgKlByZXZpZXcqIGJ1dHRvbiBvciBwcmVzcyAqQ3RybCtTaGlmdCtLKiB0byBwcmV2aWV3IHRoZSBIVE1MIGZpbGUpLg0KDQpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuDQo=